package org.openglcharts;

import java.awt.Frame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Timer;
import java.util.TimerTask;

import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import org.openglcharts.common.Value;
import org.openglcharts.listeners.LineChart2DChannel;
import org.openglcharts.listeners.Chart2DEventListener;
import org.openglcharts.listeners.LineChart2DEventListener;

import com.jogamp.opengl.util.FPSAnimator;

public class DataViewer {
	
	private Frame frame;
	private LineChart2DEventListener listener;
	private LineChart2DChannel[] channels = new LineChart2DChannel[3];
	private boolean xPressed = false;
	private boolean yPressed = false;

	public DataViewer(int width, int height) {
		
		this.listener = new LineChart2DEventListener(LineChart2DEventListener.RESIZE_POLICY_NONE);

		this.channels[0] = new LineChart2DChannel("Channel 1");
		this.channels[1] = new LineChart2DChannel("Channel 2");
		this.channels[2] = new LineChart2DChannel("Channel 3");

		this.channels[0].setColor(1.0f, 0.0f, 0.0f);
		this.channels[1].setColor(0.0f, 1.0f, 0.0f);
		this.channels[2].setColor(0.0f, 0.0f, 1.0f);

		this.listener.addChannel(this.channels[0]);
		this.listener.addChannel(this.channels[1]);
		this.listener.addChannel(this.channels[2]);

		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {

			private float x = 0.0f;

			@Override
			public void run() {
				channels[0].add(new Value(x, (float) Math.sin(x)));
				channels[1].add(new Value(x, (float) Math.sin(x - Math.PI)));
				channels[2].add(new Value(x, (float) Math.tan(x)));
				x += 0.1f;
			}

		}, 0, 50);

		GLProfile glp = GLProfile.getDefault();
		GLCapabilities cap = new GLCapabilities(glp);
		GLCanvas canvas = new GLCanvas(cap);
		canvas.addGLEventListener(this.listener);

		this.frame = new Frame("xAffect Viewer");
		frame.setSize(width, height);
		frame.add(canvas);
		frame.setVisible(true);

		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		canvas.addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				super.mouseMoved(e);
				DataViewer.this.listener.cursorMoved(new Value(e.getX(), e
						.getY()));
			}

			@Override
			public void mouseDragged(MouseEvent e) {
				super.mouseDragged(e);
				DataViewer.this.listener.cursorDragged(new Value(e.getX(), e
						.getY()));
			}
		});
		canvas.addMouseWheelListener(new MouseWheelListener() {
			@Override
			public void mouseWheelMoved(MouseWheelEvent e) {
				if (xPressed && !yPressed) {
					DataViewer.this.listener.zoom(e.getWheelRotation(),
							Chart2DEventListener.ZOOM_X);
				} else if (yPressed && !xPressed) {
					DataViewer.this.listener.zoom(e.getWheelRotation(),
							Chart2DEventListener.ZOOM_Y);
				} else {
					DataViewer.this.listener.zoom(e.getWheelRotation(),
							Chart2DEventListener.ZOOM_BOTH);
				}
			}
		});
		canvas.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				char key = e.getKeyChar();
				switch (key) {
				case 'x':
					xPressed = true;
					break;
				case 'y':
					yPressed = true;
					break;
				}
			}

			@Override
			public void keyReleased(KeyEvent e) {
				super.keyReleased(e);
				char key = e.getKeyChar();
				switch (key) {
				case 'x':
					xPressed = false;
					break;
				case 'y':
					yPressed = false;
					break;
				}
			}
		});

		FPSAnimator animator = new FPSAnimator(30);
		animator.add(canvas);
		animator.start();
	}

	public static void main(String[] args) {
		GLProfile.initSingleton();
		new DataViewer(800, 600);
	}

}
